module.exports = class BaseUtils {
  /**
   * [numberToUnitStr 数字转换单位字符串]
   * @param  {[Number]} number [description]
   * @return {[Number]}        [description]
   *
   */
  numberToUnitStr(number) {
    if (!number) {
      number = 0;
    }
    if (number === 0) {
      number = Math.random() * 1000000;
    }
    number = parseInt(number, 10);

    // 数值显示规则（四舍五入，新规则）：

    if (number >= 1e10) {
      // 1百亿及以上 显示为xxx亿，如：123亿（12345678901）
      return parseInt(number / 1e8, 10) + "亿";
    } else if (number >= 1e8) {
      // 1亿到1百亿 显示成xx.x亿，如：12.3亿（1234567890）
      return (number / 1e8).toFixed(1) + "亿";
    } else if (number >= 1e6) {
      // 100万到1亿之间显示成xxx万，如：1234万（12345678）
      return parseInt(number / 1e4, 10) + "万";
    } else if (number >= 1e5) {
      // 10万到100万之间，显示成xx.x万，如：12.3万（123456
      return (number / 1e4).toFixed(1) + "万";
    }

    // 10万以内直接显示 如：12345
    return number;
  }

  /**
   * [toDate 任意对象转日期高度容错]
   * @param  {[Object]} obj [要转换的日期]
   * @return {[type]}     [description]
   */
  toDate(obj) {
    if (
      obj instanceof Date ||
      Object.prototype.toString.call(obj) === "[object Date]"
    ) {
      return new Date(obj);
    } else if (!isNaN(obj)) {
      return new Date(parseInt(obj, 10)); // 数字或数字字符串转日期
    } else if (!isNaN(Date.parse(obj))) {
      return new Date(Date.parse(obj)); // UTC格式字符串转日期
    }
    return new Date(); // null, undefined, 0, '' 均返回当前时间
  }

  /**
   * [formatDate 格式化显示日期时间]
   * @param  {[String | Number]} date [待显示的日期时间，可以为数字形式]
   * @param  {[String]} fmt [需要显示的格式，例如YYYY-MM-dd hh:mm:ss]
   * @return {[String]}   [格式化好的时间]
   */
  formatDate(date, fmt) {
    date = this.toDate(date); // 保证date是日期类型(时间戳或UTC字符串转日期)
    if (!fmt) {
      fmt = "YYYY-MM-dd hh:mm:ss";
    }
    const o = {
      y: date.getFullYear(),
      M: date.getMonth() + 1,
      d: date.getDate(),
      h: date.getHours(),
      m: date.getMinutes(),
      s: date.getSeconds(),
    };
    try {
      return fmt.replace(/(Y+|M+|d+|h+|m+|s+)/g, function (item) {
        const len = item.length;

        return ((len > 1 ? "0" : "") + o[item.slice(-1)]).slice(
          -(len > 2 ? len : 2)
        );
      });
    } catch (e) {
      console.error(e);
      return "";
    }
  }

  /**
   * 1s = 1000ms
   * 1m = 60 * 1000ms
   * 1h = 60 * 60 * 1000
   * 1d = 24 * 60 * 60 * 1000
   *
   * [getTimeSpan 转换阶梯时间]
   * @param  {[Number]} timestamp [时间戳]
   * @param  {[String]} fmt [需要显示的格式，例如YYYY-MM-dd hh:mm:ss]
   * @return {[String]}      [转换后的时间字符串]
   */
  getTimeSpan(timestamp, fmt) {
    timestamp = parseInt(timestamp, 10);
    if (timestamp.toString().length === 10) {
      timestamp = timestamp * 1000;
    }
    const nowDate = new Date();
    const current = nowDate.getTime();
    const differe = current - timestamp; // 差值
    // const aYearAgo = new Date(nowDate)  // 从当前时间前置一年，获取到当时的时间戳
    // aYearAgo.setFullYear(nowDate.getFullYear() - 1);

    // if (aYearAgo.getTime() > timestamp) {
    // 	// 大于一年前，显示YYYY.mm.dd（例：2016.05.20）
    // 	return this.formatDate(timestamp, 'YYYY.mm.dd');
    // }
    if (differe > 0) {
      if (differe > 864e6) {
        // 10天前，显示mm.dd hh: mm（例：04.05 16:05）
        // return this.formatDate(timestamp, 'mm.dd hh:mm')
        return this.formatDate(timestamp, fmt || "YYYY.MM.dd");
      } else if (differe > 2592e5) {
        // 小于10天（含10天），显示x天前；
        return parseInt(differe / 864e5, 10) + "天前";
      } else if (differe > 1728e5) {
        // 2天到3天之前前天；
        return "前天";
      } else if (differe > 864e5) {
        // 1天到2天之间，显示昨天；
        return "昨天";
      } else if (differe > 36e5) {
        // 小于一天，显示x小时前；
        return parseInt(differe / 36e5, 10) + "小时前";
      } else if (differe > 6e4) {
        // 小于1小时，显示x分钟前；
        return parseInt(differe / 6e4, 10) + "分钟前";
      }

      // 小于1分钟，显示“刚刚”；
      return "刚刚";
    } else {
      return this.formatDate(timestamp, fmt || "YYYY.MM.dd");
    }
  }

  /**
   * @function zeroize 数字补零
   * @param {Number} number
   */
  zeroize(number) {
    return number >= 10 ? number : (number = "0" + number);
  }

  /**
   * @function getType
   * @param {Object} origin 原始数据
   * @param {String} type 数据类型 string,number,boolean,undefined,null,object,array,function
   * @return {String} 返回数据类型string,number,boolean,undefined,null,object,array,function
   */
  getType(origin) {
    const originType = Object.prototype.toString.call(origin);
    const len = originType.length;
    return originType.substring(8, len - 1).toLowerCase();
  }

  /**
   * @function installTree 组装树
   * @param {Array} data 要处理的树数组
   * @param {Object} options 默认配置
   */
  installTree(data = [], options = {}) {
    let {
      id = 0,
      mode = "tree", // mode: tree, object, array
      key_id = "id",
      key_fid = "fid",
    } = options;
    id = parseInt(id, 10);
    if (id === 0 && mode === "array") {
      return data;
    }

    const dict = {},
      filterDict = {};
    // 组装到字典
    data.forEach((item) => {
      dict[item[key_id]] = item;
    });

    if (id === 0 && mode === "object") {
      return dict;
    }

    // 过滤出当前id和其子集
    for (let i in dict) {
      const item = dict[i];
      const fid = item[key_fid];
      const idKey = item[key_id];
      if (fid == id || idKey == id) {
        filterDict[idKey] = item;
      }
    }
    // 返回过滤后的对象
    if (mode === "object") {
      return filterDict;
    }
    // 返回过滤后的数组
    if (mode === "array") {
      return Object.values(filterDict);
    }

    // 组装树
    const loopDict = (dict) => {
      for (let i in dict) {
        const item = dict[i];
        const father = item[key_fid];
        const fatherData = dict[father];
        if (father > 0 && fatherData) {
          if (!fatherData.children) {
            fatherData.children = [];
          }
          fatherData.children.push(item);
        }
      }
    };
    if (dict[id]) {
      loopDict(filterDict);
      return filterDict[id];
    } else {
      loopDict(dict);
      for (let i in dict) {
        const item = dict[i];
        if (item[key_fid]) {
          delete dict[item[key_id]];
        }
      }
      return dict;
    }
  }

  filterObjectEmpty(data = {}) {
    Object.keys(data).forEach((item) => {
      if (data[item] == "") {
        delete data[item];
      }
    });
    return data;
  }
};
